fix: preserve unreadCount when inserting chats via messaging-history.set#2561
fix: preserve unreadCount when inserting chats via messaging-history.set#2561zcag wants to merge 2 commits into
Conversation
The messaging-history.set handler built chatsRaw entries with only remoteJid, remoteLid, instanceId, and name — dropping chat.unreadCount entirely. Chats inserted via this path always got unreadMessages = 0 (Prisma default) regardless of what WhatsApp's server sent in the history sync payload. The chats.upsert handler already maps this correctly: unreadMessages: chat.unreadCount !== undefined ? chat.unreadCount : 0 Apply the same mapping here so that unread counts synced from the server during initial history import are actually persisted.
Reviewer's guide (collapsed on small PRs)Reviewer's GuidePreserves WhatsApp server-provided unread counts when importing chats via the Sequence diagram for preserving unread counts during messaging-history.set importsequenceDiagram
actor User
participant WhatsAppServer
participant BaileysStartupService
participant PrismaChat
participant FindChatsApi
User->>WhatsAppServer: Connect new instance
WhatsAppServer-->>BaileysStartupService: messaging-history.set
BaileysStartupService->>BaileysStartupService: Build chatsRaw entries
BaileysStartupService->>BaileysStartupService: Set unreadMessages = chat.unreadCount ?? 0
BaileysStartupService->>PrismaChat: [persist chatsRaw with unreadMessages]
User->>FindChatsApi: findChats(instanceId)
FindChatsApi->>PrismaChat: [read chats with unreadMessages]
PrismaChat-->>FindChatsApi: chats including unreadMessages
FindChatsApi-->>User: chats with correct unreadCount
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - I've left some high level feedback:
- The inline
chatsRawtype is starting to diverge from other chat upsert logic (e.g. the handler that already mapsunreadMessages); consider extracting a shared type/interface for these raw chat objects so future changes (like adding fields) stay in sync across the different insert/update paths. - By forcing
unreadMessages: chat.unreadCount ?? 0you override any DB-level default; if the intent is to distinguish between "server explicitly said 0" and "no unread count provided", you might want to passundefinedwhenchat.unreadCountisundefinedand let the existing schema/defaults handle that case.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The inline `chatsRaw` type is starting to diverge from other chat upsert logic (e.g. the handler that already maps `unreadMessages`); consider extracting a shared type/interface for these raw chat objects so future changes (like adding fields) stay in sync across the different insert/update paths.
- By forcing `unreadMessages: chat.unreadCount ?? 0` you override any DB-level default; if the intent is to distinguish between "server explicitly said 0" and "no unread count provided", you might want to pass `undefined` when `chat.unreadCount` is `undefined` and let the existing schema/defaults handle that case.Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
- Extract ChatRaw shared type (remoteJid, instanceId, name, unreadMessages)
used by both chats.upsert and messaging-history.set insert paths
- messaging-history.set chatsRaw now typed as (ChatRaw & { remoteLid })[]
- Pass chat.unreadCount directly instead of coercing undefined to 0,
letting the DB default handle the missing-value case
|
Pushed a commit addressing both points, thanks! |
|
Thanks @sourcery-ai — both points are already addressed in the current diff:
The PR description has been updated to match — it previously described a |
|
🟢 👍 Na branch certa ( |
dpaes
left a comment
There was a problem hiding this comment.
Approved.
Reviewed independently against develop:
- Real bug confirmed: in
messaging-history.setthe assembled chat object never includedunreadMessages, so thecreateManyinsert always fell back to the column default0— every history-synced chat lost its unread count. AddingunreadMessages: chat.unreadCountfixes it, and theJSON.parse(JSON.stringify(...))round-trip drops the key when the value isundefined, so the column default still applies in that case (identical to before) while the real value is preserved when present. - I also checked the change on the
chats.upsertpath (chat.unreadCount !== undefined ? ... : 0→chat.unreadCount): thechatsToInsertobject is shared between the webhook and the DBcreateMany. WhenunreadCountis undefined, Prisma omits it and the column default0still applies, so the DB outcome is unchanged. Every internal consumer ofunreadMessages(the SQL reads inchannel.serviceandupdateChatUnreadMessages) reads from the DB column, never from the webhook payload — so there is no internal dependency on the payload carrying0. The only observable difference is that external webhook consumers receive the key omitted instead of0when no count is reported, which the PR documents as intentional. No regression. ChatRawis coherent (no name collision; compiles cleanly understrict:false).
LGTM 👍
Non-blocking suggestion for a follow-up commit (not required to merge): ChatRaw could declare the baileys-nullable fields more precisely as name?: string | null and unreadMessages?: number | null (baileys' IConversation.name/unreadCount are string|null/number|null). Harmless under the current strict:false config — just a typing-precision nit you could fold in next time.
Problem
When a new instance connects and Baileys fires
messaging-history.setto bulk-import chat history, thechatsRawentries are built with onlyremoteJid,remoteLid,instanceId, andname. Thechat.unreadCountfield — which WhatsApp's server sends in the history sync payload (Conversation.unreadCount, protobuf field #6) — is silently dropped.As a result, every chat inserted through this path gets
unreadMessages = 0(the Prisma column default), regardless of the actual unread state on the server. ThefindChatsendpoint then returnsunreadCount: 0for all historically-synced chats, even when the user has genuine unread messages.Root cause
The
CHATS_UPSERTinsert path mapped the field (coercing missing values to0):The
messaging-history.sethandler simply never included the equivalent mapping, sochat.unreadCountwas dropped for every historically-synced chat.Fix
ChatRawtype so the raw chat objects built for both insert paths stay in sync as fields are added.messaging-history.sethandler, includeunreadMessages: chat.unreadCountin thechatsRaw.push(...)call (previously dropped).CHATS_UPSERTinsert path to the samechat.unreadCountform: pass the value through as-is — i.e.undefinedwhen the server didn't send a count — and let the Prisma column default apply, rather than coercing to0. This keeps both paths consistent and preserves the distinction between "server explicitly reported 0 unread" and "no unread count provided".Testing
messaging-history.setfire during initial syncPOST /chat/findChats/{instance}— chats should now reflect the server-side unread counts instead of all returningunreadCount: 0Summary by Sourcery
Bug Fixes: